package com.dyh.quickdemozwei;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dyh.quickdemozwei.util.DateUtil;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
public class TestBinjouThread {

    @Test public void test(){
//      String url = "/xxx/xasx/xax.zip";
      String url = "dawd.zip";

       String[] arr = url.split("/");

        System.out.println();
    }


    @Setter@Getter@AllArgsConstructor
    class Order{
        String id;
        Date updateTime;
    }

    @Setter@Getter@AllArgsConstructor
    class WorkPackage<T>{
        List<T> data;
        Function<T,String> idfc;
        Comparator<T> comparator;

        List<String> cancelIds;


    }



    WorkPackage trans2wp(List<Order> orders){
        WorkPackage workPackage = new WorkPackage(orders,
                (Function<Order,String>)Order::getId,Comparator.comparing(e->((Order)e).getUpdateTime()),new ArrayList<>());
        return workPackage;
    }



    @Setter@Getter
    class WorkCoordinator<T>{
        Function<T,String> idfc;
//        Map<String,T> id2data=new HashMap<>();
        LinkedBlockingQueue<T> blockingQueue = new LinkedBlockingQueue();
        Comparator<T> comparator;
        Consumer<T> consumer;
        int coreNum;

        List<LinkedBlockingQueue<T>> splitQueue;


        public void announce(T data){
            try {
                blockingQueue.put(data);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//            String key = idfc.apply(data);
//            T dataOld = id2data.get(key);
//            if (dataOld==null){
//                id2data.put(key,data);
//            }
//            else {
//                if (comparator.compare(data,dataOld)>0){
//                    id2data.put(key,data);
//                }
//            }
        }

        public void init(){
            splitQueue = new ArrayList<>(coreNum);
            for (int i = 0;i<coreNum;i++){
                splitQueue.add(new LinkedBlockingQueue<>(3));
            }
            ManagerThread managerThread = new ManagerThread();
            managerThread.setName("managerThread");
            managerThread.start();
            
            for (int i = 0;i<coreNum;i++){
                WorkThread workThread = new WorkThread(i);
                workThread.setName("workThread-"+i);
                workThread.start();
            }
        }

 
        class WorkThread extends Thread{
            int index;

            public WorkThread(int index) {
                this.index = index;
            }

            @Override
            public void run() {
                log.info("WorkThread-{} 启动",index);
                for (;;){
                    try {
                       T t = splitQueue.get(index).take();
                       log.info("WorkThread-{} 取得数据",index);
                       consumer.accept(t);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        class ManagerThread extends Thread{
            @Override
            public void run() {
                log.info("ManagerThread启动");
                for (;;){
                    List<T> list = new ArrayList<>();
                    blockingQueue.drainTo(list);
                    Map<String,T> finalMap = new HashMap<>();
                    for (T t : list) {
                        String key = idfc.apply(t);
                        T oldData = finalMap.get(key);
                        if (oldData==null){
                            finalMap.put(key,t);
                        }
                        else {
                            if (comparator.compare(t,oldData)>0)
                                finalMap.put(key,t);
                        }
                    }

                    /*放一个换下个队列防止都满*/
                    int shift = 0;
                    for (T value : finalMap.values()) {
                        try {
                            LinkedBlockingQueue queue = splitQueue.get(shift);
                            queue.put(value);
                            log.info("shift={} queueSize={}",shift,queue.size());
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        shift++;
                        if (shift==coreNum)
                            shift=0;
                    }

                }
            }
        }

      


      


    }

    @Test
    public void test1() throws InterruptedException {
        Date dateOld = DateUtil.str2Date("2001-01-02 00:00:00");
        List<Order> t1Orders = Lists.newArrayList(
                new Order("1",dateOld),
                new Order("2",dateOld),
                new Order("3",dateOld)
        );




        List<Order> t2Orders = Lists.newArrayList(
                new Order("2",new Date()),
                new Order("4",new Date())
        );
        
        Consumer<Order> consumer = e->{
            log.info("{} 开始执行-id-{}  {}",Thread.currentThread().getName(),e.getId(),JSON.toJSONString(e));
            try {
                Thread.sleep(2000L);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            log.info("{} 结束执行-id-{}  {}",Thread.currentThread().getName(),e.getId(),JSON.toJSONString(e));
        };

        
        Comparator<Order> orderComparator = Comparator.comparingLong(e->e.getUpdateTime().getTime());

        WorkCoordinator<Order> workCoordinator = new WorkCoordinator<>();
        workCoordinator.setCoreNum(3);
        workCoordinator.setIdfc(Order::getId);
        workCoordinator.setComparator(orderComparator);
        workCoordinator.setConsumer(consumer);
        workCoordinator.init();
        

        t1Orders.forEach(workCoordinator::announce);


        t2Orders.forEach(workCoordinator::announce);


        Thread.sleep(1000L*60L);
        /*断点法不准*/
        System.out.println();

    }

//    @Test
//    public void test() throws InterruptedException {
//        Date dateOld = DateUtil.str2Date("2001-01-02 00:00:00");
//        List<Order> t1Orders = Lists.newArrayList(
//                new Order("1",dateOld),
//                new Order("2",dateOld),
//                new Order("3",dateOld)
//        );
//
//
//
//
//        List<Order> t2Orders = Lists.newArrayList(
//                new Order("2",new Date()),
//                new Order("4",new Date())
//        );
//
//        WorkCoordinator<Order> workCoordinator = new WorkCoordinator<>();
//        Comparator<Order> orderComparator = Comparator.comparingLong(e->e.getUpdateTime().getTime());
//        workCoordinator.setIdfc(Order::getId);
//        workCoordinator.setComparator(orderComparator);
//
//
//        t1Orders.forEach(workCoordinator::announce);
//
//        Thread t1 = new Thread(()->{
//            log.info("{}", JSON.toJSONString(workCoordinator.id2data.get("2")));
//            try {
//                Thread.sleep(2000L);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            log.info("{}",JSON.toJSONString(workCoordinator.id2data.get("2")));
//
//        });
//        t1.setName("t1");
//        t1.start();
//
//        log.info("mainSleep start");
//        Thread.sleep(1000L);
//        log.info("mainSleep end");
//        t2Orders.forEach(workCoordinator::announce);
//
//        t1.join();
//
//        System.out.println();
//
//    }

    public static void main(String[] args) {

        List l1 = Lists.newArrayList(1,2,3);
        List l2 = Lists.newArrayList(2,3);




        List<List> waitQueue = new ArrayList<>();
        waitQueue.add(l1);
        waitQueue.add(l2);


        Iterator iterator = waitQueue.iterator();
        while (iterator.hasNext()){

        }

    }

}
